package com.lyxs916.network;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;

import com.lyxs916.utilslibrary.ui.ToastUtils;
import com.lyxs916.widget.factory.CustomDialogFactory;
import com.lyxs916.widget.factory.CustomLoadingFactory;
import com.lyxs916.widget.loading.bar.LoadingBar;
import com.lyxs916.widget.loading.dialog.LoadingDialog;
import com.lyxs916.common.HeadType;
import com.lyxs916.common.HostType;
import com.lyxs916.corelib.core.application.Global;
import com.lyxs916.corelib.core.view.CoreOnLoadingBarListener;
import com.lyxs916.utilslibrary.ui.LogUtils;
import com.lyxs916.httpresponse.ContextData;
import com.lyxs916.utils.HttpLocalUtils;

import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.concurrent.TimeoutException;

import retrofit2.adapter.rxjava.HttpException;

import static com.lyxs916.corelib.core.application.Global.myApp;


public abstract class HttpCallBack<ResultType> {

    protected Context mContext;
    protected CoreOnLoadingBarListener mCoreOnLoadingBarListener;
    /**
     * 提示语
     */
    protected String mHint = "";
    /**
     * 设置不可点击的View
     */
    protected View[] mEnableView;
    /**
     * 是否可以取消
     */
    protected boolean mIsCancelable = false;
    /**
     * 是否显示加载对话框,true 可以取消，false 不可取消
     */
    protected boolean mIsShowLoadding = true;
    /**
     * 加载对话框显示的位置
     */
    protected ViewGroup mShowLoaddingLocationView;

    /**
     * 指定头部类型
     * {@link HeadType}
     */
    protected int mHeadType = 0;
    /**
     * 指定头部类型
     * {@link HostType}
     */
    protected int mHostType = HostType.TYPE_DEFAULT;


    public HttpCallBack(Builder buider) {
        mHint = buider.mHint;
        mEnableView = buider.mEnableView;
        mIsCancelable = buider.mIsCancelable;

        mIsShowLoadding = buider.mIsShowLoadding;
        mHeadType = buider.mHeadType;
        mHostType = buider.mHostType;
        mShowLoaddingLocationView = buider.mShowLoaddingLocationView;
        mCoreOnLoadingBarListener = buider.mCoreOnLoadingBarListener;
        this.mContext = buider.mContext;
    }

    /**
     * 订阅开始时调用
     * 请求开始
     */
    public void onStart() {
        LogUtils.e("onStart");
        //设置View的不可点击
        if (mEnableView != null) {
            for (View view : mEnableView) {
                view.setEnabled(false);
            }
        }

        /**
         * 显示加载对话框
         *
         * 默认dialog对话框
         * LoadingDialog.make((Context) mBasePresenter.mvpView).setCancelable(mIsCancelable).setMessage(mHint).show();
         */
        if (mIsShowLoadding && mContext != null) {
            //自定义dialog对话框
            LoadingDialog.make(mContext, new CustomDialogFactory())
                    .setMessage(mHint)//提示消息
                    .setCancelable(mIsCancelable)
                    .create()
                    .show();
        }
    }

    /**
     * 请求完成
     */
    public void onCompleted() {
        LogUtils.e("onCompleted");
        if (mEnableView != null) {
            for (View view : mEnableView) {
                view.setEnabled(true);
            }
        }
        dismissUi();
    }

    /**
     * 取消加载框的显示
     */
    protected void dismissUi() {
        //加载dialog取消
        LoadingDialog.cancel();
        //错误状态的取消
        if (mShowLoaddingLocationView != null) {
            LoadingBar.cancel(mShowLoaddingLocationView);
        }
    }

    /**
     * 请求出错
     *
     * @param error
     */
    public void onError(Throwable error) {
        LogUtils.e("onError8888888888666666666666土土");
        onCompleted();

        ContextData data = new ContextData();
        String errString = "";
        int errCode;
        if (error != null) {
            LogUtils.e("onError->error, error.toString()");
            errCode = -1;
        }
        if (!HttpLocalUtils.isNetworkAvailable(myApp)) {
            errString = "请检查网络设置";
            errCode = -2;
        } else if (error instanceof HttpException) { // 网络错误
            HttpException httpEx = (HttpException) error;
            if (httpEx.getMessage().contains("timed out")) {
                errString = "连接超时";
            } else if (httpEx.code() == 500) {
                errString = "服务君累趴下啦";
            } else if (httpEx.code() == 0) {
                errString = "服务君累趴下啦.";
            } else if (httpEx.code() == 403) {
                errString = "禁止访问";
            } else if (httpEx.code() == 404) {
                errString = "资源不存在";
            } else {
                //其他错误
                errString = "未知网络错误";
            }
            errCode = httpEx.code();

        } else if (error instanceof SocketException) {
            //java.net.SocketException: sendto failed: ECONNRESET (Connection reset by peer)
            //服务器的并发连接数超过了其承载量，服务器会将其中一些连接关闭；
            //如果知道实际连接服务器的并发客户数没有超过服务器的承载量，则有可能是中了病毒或者木马，引起网
            errString = "请求过于频繁,请稍后再试";
            errCode = -3;
        } else if (error instanceof SocketTimeoutException || error instanceof TimeoutException) {
            //超时
            errString = "连接超时";
            errCode = -4;

        } else if (error instanceof UnknownHostException) {
            errString = "请检查网络设置";
            errCode = -2;
        } else {
            errString = "未知的错误";
            errCode = -200;
        }

        data.setTitle(errString);
        data.setErrCode(errCode);

        ToastUtils.getToastShort(errString);

        //加载错误时显示的View
        if (mShowLoaddingLocationView != null) {
            final String finalErrString = errString;
            final CustomLoadingFactory clf = new CustomLoadingFactory()
                    .setMessage(finalErrString)
                    .setIcon(Global.defeatIcon);

            LoadingBar.make(mShowLoaddingLocationView, clf)
                    .setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            if (mCoreOnLoadingBarListener != null) {
                                mCoreOnLoadingBarListener.coreOnLoadingBarListener(mShowLoaddingLocationView);
                            }
                        }
                    }).show();

        }

    }

    /**
     * 请求成功
     *
     * @param result 创建Subscriber时的泛型类型
     */
    public void onSuccess(ResultType result) {
        onSuccess(result, true);
    }

    /**
     * @param result
     * @param isHanderError 是否对错误信息处理
     */
    public final void onSuccess(ResultType result, boolean isHanderError) {

//        if (statusChangListener != null) {
//            statusChangListener.complete();
//        }
//        if (loadingAndRetryManager != null) {
//            if (result instanceof BaseHttpResponse && isHanderError) {
//                if (!((BaseHttpResponse) result).isSucceed()) {
//                    loadingAndRetryManager.showRetry(new ContextData(((BaseHttpResponse) result).getResult(), ((BaseHttpResponse) result).getStatusCodeMsg()));
//                } else {
//                    loadingAndRetryManager.showContent();
//                }
//            } else {
//                loadingAndRetryManager.showContent();
//            }
//        }
    }

    /**
     * 说明:http 初始化构建
     * 作者： 杨阳; 创建于：  2017-06-09  10:05
     */
    public static class Builder {

        protected Context mContext;

        protected CoreOnLoadingBarListener mCoreOnLoadingBarListener;

        /**
         * 加载对话框是否可以取消
         */
        protected boolean mIsCancelable = false;
        /**
         * 请求时不可点击的View
         */
        protected View[] mEnableView;
        /**
         * 加载时的提示语
         */
        protected String mHint = null;
        /**
         * 是否显示加载对话框
         */
        protected boolean mIsShowLoadding = true;
        /**
         * 加载对话框显示的位置
         */
        protected ViewGroup mShowLoaddingLocationView;

        /**
         * 指定头部类型
         * {@link HeadType}
         */
        protected int mHeadType = 0;

        /**
         * 指定头部类型
         * {@link HostType}
         */
        protected int mHostType = HostType.TYPE_DEFAULT;

        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //                                 说明：    方法区              2017-06-09  10:04
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public Builder() {

        }

        public Builder(Context context) {
            this.mContext = context;
        }


        /**
         * 说明:设置请求添加的头部
         * 作者： 杨阳; 创建于：  2017-06-08  13:51
         * {@link HeadType}
         */
        public Builder setHttpHead(HeadType type) {
            mHeadType = type.getKey();

            return this;
        }

        /**
         * 说明:设置请求的主机地址
         * 作者： 杨阳; 创建于：  2017-06-08  13:51
         * {@link HostType}
         */
        public Builder setHostType(@HostType.HostTypeChecker int type) {
            mHostType = type;
            return this;
        }


        /**
         * 显示加载的监听
         *
         * @param isShowLoadding 是否显示加载对话框
         * @return 错误时显示的对话框显示的位置
         */
        public Builder setShowLoading(Context context, boolean isShowLoadding) {
            this.mContext = context;
            return setShowDefeatView(isShowLoadding, null);
        }

        /**
         * 错误页面的回调监听,主要用于网络请求失败或错误，把指定ViewGroup页面替换为定义的View
         *
         * @param viewGroup 错误时显示的对话框显示的位置
         * @return Builder
         */
        public Builder setShowDefeatView(boolean isShowLoadding, ViewGroup viewGroup) {
            mIsShowLoadding = isShowLoadding;
            mShowLoaddingLocationView = viewGroup;

            return this;
        }

        /**
         * 加载时的提示语
         *
         * @param mHint 提示语
         * @return Builder
         */
        public Builder setHint(String mHint) {
            this.mHint = mHint;
            return this;
        }

        /**
         * 请求时不可点击的View
         *
         * @param view 传入不可点击的view
         * @return Builder
         */
        public Builder setEnableView(View... view) {
            this.mEnableView = view;
            return this;
        }

        /**
         * 加载对话框是否可以取消
         *
         * @param mIsCancelable true 可以取消，false 不可取消
         * @return Builder
         */
        public Builder setCancelable(boolean mIsCancelable) {
            this.mIsCancelable = mIsCancelable;
            return this;
        }

        /**
         * 错误页面的点击回调
         *
         * @param mCoreOnLoadingBarListener
         */
        public Builder setmCoreOnLoadingBarListener(CoreOnLoadingBarListener mCoreOnLoadingBarListener) {
            this.mCoreOnLoadingBarListener = mCoreOnLoadingBarListener;
            return this;
        }


    }


}
